home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
SciAn
/
src
/
ScianNetObjects.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
33KB
|
1,513 lines
/* ScianNetObjects.c
* John R. Murray
* June 1992
* Stuff for transmitting and receiving objects over sockets.
*/
#include "Scian.h"
#include "ScianIDs.h"
#include "ScianTypes.h"
#include "ScianNetObjects.h"
#include "ScianSockets.h"
#include "ScianLists.h"
#include "ScianErrors.h"
#include "ScianWindows.h"
#include "ScianObjWindows.h"
#include "ScianDatasets.h"
#include "ScianNames.h"
/* the following .h files are ONLY included for extern classes */
#include "ScianArrays.h"
#include "ScianTimers.h"
#include "ScianVisObjects.h"
/* this one's here for NewAtomicPalette function definition */
#include "ScianColors.h"
#ifndef DEBUGSOCKETS
#define DEBUGSOCKETS
#endif
/* if the main body of the object is smaller than this, an obj without the
* extra bytes gets sent */
#define NO_SIZE_THRESHOLD 1024
static ObjPtr allPublished;
#ifdef SAVEDELETED
static ObjPtr allDeletedPublished;
#endif
#ifdef SOCKETS
unsigned int lastNetworkID = 0;
unsigned long GetNetworkID()
{
return ++lastNetworkID;
}
void AssembleNetObjectVars (vnode, start)
VarsPtr vnode;
char **start;
{
if (!vnode)
return;
if (!ThisWouldBeAReallyBadThing(vnode -> name))
{
if (!vnode -> value)
{
fprintf(stderr, "WARNING!! Sending var %ld with value NULLOBJ\n", vnode -> name);
}
#ifdef DEBUGSOCKETS
#ifdef DEBUG
fprintf(stderr, "var %d\n", vnode -> name);
#endif
sprintf(*start, "%d ", vnode -> name);
*start += strlen(*start);
#else
*((NameTyp *) *start) = HTON_NAMETYP(vnode -> name);
*start += sizeof(NameTyp);
#endif
}
AssembleNetObjectVars (vnode -> left, start);
AssembleNetObjectVars (vnode -> right, start);
}
char *GetNetTypeStr(obj, connection)
ObjPtr obj, connection;
{
ObjPtr class;
class = ClassOf(obj);
if (class == iconDataset)
return NET_ICONDATASET;
else if (class == icon1DVector)
return NET_ICON1DVECTOR;
else if (class == icon2DVector)
return NET_ICON2DVECTOR;
else if (class == icon3DVector)
return NET_ICON3DVECTOR;
else if (class == icon4DVector)
return NET_ICON4DVECTOR;
else if (class == icon1DScalar)
return NET_ICON1DSCALAR;
else if (class == icon2DScalar)
return NET_ICON2DSCALAR;
else if (class == icon3DScalar)
return NET_ICON3DSCALAR;
else if (class == icon4DScalar)
return NET_ICON4DSCALAR;
else if (class == data3DScalar)
return NET_DATA3DSCALAR;
else if (class == data2DScalar)
return NET_DATA2DSCALAR;
else if (class == data1DVector)
return NET_DATA1DVECTOR;
else if (class == data3DUnstructSurface)
return NET_DATA3DUNSTRUCT;
else if (class == datasetClass)
return NET_DATASET;
else if (class == dataFormClass)
return NET_DATAFORM;
else if (class == stringClass)
return NET_STRING;
else if (class == objClass && IsInt(obj))
return NET_INTEGER;
else if (class == objClass && IsReal(obj))
return NET_REAL;
else if (class == objClass)
return NET_PLAINOBJECT;
else if (class == arrayClass)
#if MACHINE == IRIS4D
#ifdef FASTSOCKETS
return NET_REALARRAYRAW;
#else
if (GetPredicate(connection, FASTSOCKET))
{
return NET_REALARRAYRAW;
}
else
{
return NET_REALARRAYASCII;
}
#endif
#else
return NET_REALARRAYASCII;
#endif
else if (class == objectArrayClass)
return NET_OBJECTARRAY;
else if (class == timedObjClass)
return NET_TIMEDOBJECT;
else if (class == paletteClass)
return NET_PALETTE;
else if (class == visIcon)
{
fprintf(stderr, "sending visIcon\n");
return NET_VISICON;
}
else
{
fprintf(stderr, "trying to transmit obj of unrecognized class\n");
fprintf(stderr, "class = 0x%x\n", class);
return NET_UNIMPLEMENTED;
}
}
void TransmitObject(obj, connection, flag)
ObjPtr obj, connection;
Bool flag;
/* transmit obj across connection. if flag, send OBJ! message header, or not */
{
char buf[1024];
char *bufp;
int sock;
int networkID;
ObjPtr networkIDPtr;
NetFlagsTyp netFlags;
FuncTyp method;
FlagsTyp flagstmp;
networkID = PublishObject(obj);
sock = ((ConnectionPtr) connection) -> sock;
if (sock < 0)
return;
bufp = buf;
if (flag)
{
sprintf(bufp, "%s ", NO_MESG_OBJECT);
bufp += strlen(bufp);
}
/* sending network type identifier */
sprintf(bufp, "%s ", GetNetTypeStr(obj, connection));
bufp += strlen(bufp);
/* sending network ID number */
#ifdef DEBUG
fprintf(stderr, "xmitting netid %ld\n", networkID);
#endif
sprintf(bufp, "%ld ", networkID);
bufp += strlen(bufp);
/* send object flags */
flagstmp = obj -> flags;
flagstmp = flagstmp & ~ISPUBLISHED;
if (GetVar(obj, ADVERTISED))
{
flagstmp = flagstmp | ISREMOTEADVERTISED;
}
sprintf(bufp, "%ld ", flagstmp);
bufp += strlen(bufp);
/* send network flags */
netFlags = ( !obj -> class ? NO_NULL_CLASS : 0 )
| ( !obj -> vars ? NO_NULL_VARS : 0 )
| ( !obj -> methods ? NO_NULL_METHODS : 0 )
| ( !obj -> depends ? NO_NULL_DEPENDS : 0 );
sprintf(bufp, "%ld ", netFlags);
bufp += strlen(bufp);
/* send variables */
AssembleNetObjectVars(obj -> vars, &bufp);
sprintf(bufp, "%d ", NO_LAST_VAR);
bufp += strlen(bufp);
#ifdef DEBUG
fprintf(stderr, "%s", buf);
#endif
if (bufp - buf > 1024)
{
fprintf(stderr, "TransmitObject: overran buffer!\n");
}
writen(sock, buf, bufp - buf);
method = GetMethod(obj, TRANSMITEXTRA);
if (method)
{
/*BIG HAK!*/
#if MACHINE == RS6000
#else
if (GetPredicate(connection, FASTSOCKET)
&& (method == TransmitExtraStuffRealArrayAscii))
{
#ifdef DEBUG
fprintf(stderr, "fast\n");
#endif
TransmitExtraStuffRealArrayRaw(obj, connection);
}
else
#endif
{
(* method) (obj, connection);
}
}
/* send line terminator */
buf[0] = '\n';
buf[1] = '\0';
#ifdef DEBUG
fprintf(stderr, "%s", buf);
#endif
writen(sock, buf, strlen(buf));
}
#define ROS_BEGIN 0 /* startup state */
#define ROS_READ_NET_TYPE 1 /* reading the type of this object */
#define ROS_READ_FLAGS 2 /* reading the object flags */
#define ROS_READ_NETFLAGS 3 /* reading the net flags */
#define ROS_READ_VARS 4 /* reading the vars */
#define ROS_ERROR 5 /* blammo */
#define ROS_DONE 6 /* I'm done */
#define ROS_READ_NETWORKID 7 /* reading the network identifier */
ObjPtr ReceiveObject(connection, remoteChCount)
ObjPtr connection;
unsigned long remoteChCount;
{
int state;
ObjPtr retVal;
char objType, inChar;
int someDigits;
unsigned long ltmp;
int networkID;
int sock;
char s[100];
int netID = 0;
int varNum = 0;
int debug = 0; /* setting this to 1 will fprintf the internal states */
ObjPtr process;
ltmp = 0; /* we'll have to do something else with ltmp when we make this reentrant */
state = ROS_BEGIN;
sock = ((ConnectionPtr) connection) -> sock;
if (sock < 0)
{
ReportError("ReceiveObject", "Bad socket");
return ObjFalse;
}
process = GetObjectVar("ReceiveObject", connection, OWNERPROCESS);
if (!process)
{
ReportError("ReceiveObject", "connection has no OWNERPROCESS");
return ObjFalse;
}
while (state != ROS_DONE)
{
switch(state)
{
case ROS_BEGIN:
if (debug) fprintf(stderr, "state = BEGIN\n");
state = ROS_READ_NET_TYPE;
s[0] = '\0';
break;
case ROS_READ_NET_TYPE: /* initial entry assumes s == "" */
if (debug) fprintf(stderr, "state = READ_NET_TYPE\n");
if (1 == read(sock, &inChar, 1))
{
#if 0
if (inChar == '\n' || inChar == '\0')
{
((ConnectionPtr) connection) -> gotCmdEnd = true;
ltmp = 0;
state = ROS_ERROR;
}
else
#endif
if (!isspace(inChar))
{
if (strlen(s) <= 4)
{
strncat(s, &inChar, 1); /* append one char */
}
else
{
state = ROS_ERROR; /* net type too long */
}
/* skip initial blanks */
}
else if (s[0] == '\0') /* no characters yet */
{
/* skip initial blanks */
}
else if (strlen(s) != 4)
{
state = ROS_ERROR;
}
else /* it's a space, and we've got 4 characters */
{
long cmdNum;
cmdNum = CMD(s);
if (cmdNum == CMD(NET_PLAINOBJECT))
{
retVal = NewObject(0, 0);
}
else if (cmdNum == CMD(NET_INTEGER))
{
retVal = NewInt(0);
}
else if (cmdNum == CMD(NET_REAL))
{
retVal = NewReal(0);
}
else if (cmdNum == CMD(NET_STRING))
{
retVal = NewString("");
}
#if MACHINE == IRIS4D
else if (cmdNum == CMD(NET_REALARRAYRAW))
{
retVal = NewRealArray(1, 1L);
SetMethod(retVal, TRANSMITEXTRA, TransmitExtraStuffRealArrayRaw);
SetMethod(retVal, RECEIVEEXTRA, ReceiveExtraStuffRealArrayRaw);
}
#endif
else if (cmdNum == CMD(NET_REALARRAYASCII))
{
retVal = NewRealArray(1, 1L);
}
else if (cmdNum == CMD(NET_OBJECTARRAY))
{
long dummy;
dummy = 1L;
retVal = NewArray(AT_OBJECT, 1, &dummy);
}
else if (cmdNum == CMD(NET_ICONDATASET))
{
retVal = NewObject(iconDataset, 0);
}
else if (cmdNum == CMD(NET_ICON1DVECTOR))
{
retVal = NewObject(icon1DVector, 0);
}
else if (cmdNum == CMD(NET_ICON2DVECTOR))
{
retVal = NewObject(icon2DVector, 0);
}
else if (cmdNum == CMD(NET_ICON3DVECTOR))
{
retVal = NewObject(icon3DVector, 0);
}
else if (cmdNum == CMD(NET_ICON4DVECTOR))
{
retVal = NewObject(icon4DVector, 0);
}
else if (cmdNum == CMD(NET_ICON1DSCALAR))
{
retVal = NewObject(icon1DScalar, 0);
}
else if (cmdNum == CMD(NET_ICON2DSCALAR))
{
retVal = NewObject(icon2DScalar, 0);
}
else if (cmdNum == CMD(NET_ICON3DSCALAR))
{
retVal = NewObject(icon3DScalar, 0);
}
else if (cmdNum == CMD(NET_ICON4DSCALAR))
{
retVal = NewObject(icon4DScalar, 0);
}
else if (cmdNum == CMD(NET_DATA1DVECTOR))
{
retVal = NewObject(data1DVector, 0);
}
else if (cmdNum == CMD(NET_DATA2DSCALAR))
{
retVal = NewObject(data2DScalar, 0);
}
else if (cmdNum == CMD(NET_DATA3DSCALAR))
{
retVal = NewObject(data3DScalar, 0);
}
else if (cmdNum == CMD(NET_DATA3DUNSTRUCT))
{
retVal = NewObject(data3DUnstructSurface, 0);
}
else if (cmdNum == CMD(NET_DATASET))
{
retVal = NewObject(datasetClass, 0);
}
else if (cmdNum == CMD(NET_DATAFORM))
{
retVal = NewObject(dataFormClass, 0);
}
else if (cmdNum == CMD(NET_TIMEDOBJECT))
{
retVal = NewObject(timedObjClass, 0);
}
else if (cmdNum == CMD(NET_PALETTE))
{
retVal = NewAtomicPalette();
}
else if (cmdNum == CMD(NET_VISICON))
{
retVal = NewObject(visIcon, 0);
}
else if (cmdNum == CMD(NET_UNIMPLEMENTED))
{
fprintf(stderr, "remote process transmitted unimplemented net type\ntreating it as plain object\n");
retVal = NewObject(0, 0);
}
else
{
fprintf(stderr, "unrecognized net type %4s\n", s);
return ObjFalse;
}
ltmp = 0;
someDigits = false;
state = ROS_READ_NETWORKID;
}
}
break;
case ROS_READ_NETWORKID: /* initial entry assumes ltmp == 0 && someDigits == false */
if (debug) fprintf(stderr, "state = READ_NETWORKID\n");
#ifdef DEBUGSOCKETS
if (1 == read(sock, &inChar, 1))
{
if (isspace(inChar) && (inChar != '\n') && !someDigits)
{
/* skipping blanks */
}
else if (inChar >= '0' && inChar <= '9')
{
someDigits = true;
ltmp *= 10;
ltmp += inChar - '0';
}
else if (inChar == '\0' || inChar == '\n')
{
((ConnectionPtr) connection) -> gotCmdEnd = true;
state = ROS_ERROR;
}
else if (!someDigits)
{
state = ROS_ERROR;
}
else
{
if (debug) fprintf(stderr, "setting NETWORKID to %d\n", ltmp);
networkID = ltmp;
someDigits = false;
ltmp = 0;
state = ROS_READ_FLAGS;
}
}
#else
Yabbadabba!
#endif
break;
case ROS_READ_FLAGS: /* 1st entry assumes ltmp == 0 & someDigits == false */
if (debug) fprintf(stderr, "state = READ_FLAGS\n");
#ifdef DEBUGSOCKETS
if (1 == read(sock, &inChar, 1))
{
if (isspace(inChar) && (inChar != '\n') && !someDigits)
{
/* skipping blanks */
}
else if (inChar >= '0' && inChar <= '9')
{
someDigits = true;
ltmp *= 10;
ltmp += inChar - '0';
}
else if (inChar == '\0' || inChar == '\n')
{
((ConnectionPtr) connection) -> gotCmdEnd = true;
state = ROS_ERROR;
}
else
{
retVal -> flags = ltmp;
ltmp = 0;
someDigits = false;
state = ROS_READ_NETFLAGS;
}
}
#else
Yabbadabba!
#endif
break;
case ROS_READ_NETFLAGS: /* initial entry assumes ltmp == 0 && someDigits == false */
if (debug) fprintf(stderr, "state = READ_NETFLAGS\n");
#ifdef DEBUGSOCKETS
if (1 == read(sock, &inChar,1))
{
if (isspace(inChar) && (inChar != '\n') && !someDigits)
{
/* skipping blanks */
}
else if (inChar >= '0' && inChar <= '9')
{
someDigits = true;
ltmp *= 10;
ltmp += inChar - '0';
}
else if (inChar == '\n' || inChar == '\0')
{
((ConnectionPtr) connection) -> gotCmdEnd = true;
state = ROS_ERROR;
}
else
{
/* done reading netflags */
if (debug) fprintf(stderr, "object's netflags == %lx\n", ltmp);
if (ltmp & NO_NULL_CLASS)
{
/* ignored for now */
}
if (ltmp & NO_NULL_VARS)
{
/* ignored for now */
}
if (ltmp & NO_NULL_METHODS)
{
/* ignored */
}
if (ltmp & NO_NULL_DEPENDS)
{
/* ignored */
}
ltmp = 0;
someDigits = false;
state = ROS_READ_VARS;
}
}
#else
Yabbadabba!
#endif
break;
case ROS_READ_VARS: /* initial entry assumes ltmp == 0 and someDigits == false */
/* if (debug) fprintf(stderr, "state = READ_VARS\n"); */
if (debug) fprintf(stderr, "state = READ_VARS... ");
if (1 == read(sock, &inChar, 1))
{
if (debug) fprintf(stderr, "char '%c'\n", inChar);
if (isspace(inChar) && (inChar != '\n') && !someDigits)
{
/* skipping blanks */
}
else if (inChar >= '0' && inChar <= '9')
{
someDigits = true;
ltmp *= 10;
ltmp += inChar - '0';
}
else if (inChar == '\n' || inChar == '\0')
{
((ConnectionPtr) connection) -> gotCmdEnd = true;
state = ROS_ERROR;
}
else if (ltmp != NO_LAST_VAR)
{
VarsPtr vPtr;
SetVar (retVal, ltmp, NULLOBJ);
vPtr = GetVarNode(retVal, ltmp);
vPtr -> process = process;
vPtr -> remoteNetID = NETSTUBFLAG;
vPtr -> remoteChCount = anotherDamnReferenceCount;
ltmp = 0;
someDigits = false;
}
else
{
/* that may have been the end var marker */
if (someDigits)
{
if (SanityCheckObject(retVal))
{
FuncTyp method;
method = GetMethod(retVal, RECEIVEEXTRA);
if (method)
{
(* method) (retVal, connection);
}
state = ROS_DONE;
}
else
{
ReportError("ReceiveObject", "An incoming network object failed Sanity Check");
state = ROS_ERROR;
}
}
else
{
state = ROS_ERROR;
}
}
}
break;
case ROS_ERROR: /* no assumptions on inital entry */
if (debug) fprintf(stderr, "state = ERROR\n");
ReportError("ReceiveObject", "Error in receiving network object");
return ObjFalse;
break;
default:
fprintf(stderr, "funny state in ReceiveObject!\n");
break;
}
}
SetVar(retVal, NETWORKID, NewInt(networkID));
if (remoteChCount) SetVar(retVal, REMOTECHCOUNT, NewInt(remoteChCount));
SetVar(retVal, OWNERCONNECTION, connection);
retVal -> flags = retVal -> flags | ISREMOTE;
if (debug) PrintObject(retVal);
if (debug) PrintVarTree(retVal);
NetworkIDIsWaiting(process, networkID, false);
return retVal;
}
real ReceiveRealAscii(connection)
ObjPtr connection;
{
real retVal;
int sock;
char inChar, s[100];
int si;
double time;
Bool someDigits;
si = 0;
s[si] = '\0';
someDigits = false;
time = Clock();
sock = ((ConnectionPtr) connection) -> sock;
while (Clock() < time + JOHNSTIMEOUT && !((ConnectionPtr) connection) -> gotCmdEnd)
{
if (1 == read(sock, &inChar, 1))
{
if (isspace(inChar) && (inChar != '\n') && !someDigits)
{
/* skipping blanks */
}
else if (si >= 100 || (inChar >= '0' && inChar <= '9')
|| inChar == '-' || inChar == 'e' || inChar == 'E'
|| inChar == '+' || inChar == '-' || inChar == '.')
{
someDigits = true;
s[si++] = inChar;
s[si] = '\0';
}
else
{
int len;
if (inChar == '\0' || inChar == '\n')
{
((ConnectionPtr) connection) -> gotCmdEnd = true;
}
/* make sure we read etwas that takes up the whole string */
if (someDigits && (1 != sscanf(s, "%100g%n", &retVal, &len)
|| len < strlen(s)))
{
fprintf(stderr, "bad sscanf return. s = %s, len = %d, strlen(s) = %d.\n", s, len, strlen(s));
return -1;
}
return retVal;
}
}
}
/* only got here if we timed out */
fprintf(stderr, "hack timeout in ReceiveRealAscii\n");
return -1;
}
ObjPtr TransmitExtraStuffRealArrayRaw(obj, connection)
ObjPtr obj, connection;
{
int sock;
int rank;
long *dimp;
int i;
long nels;
real *elsPtr;
sock = ((ConnectionPtr) connection) -> sock;
rank = RANK(obj);
#ifdef DEBUG
fprintf(stderr, "sending rank = %d.. ", rank);
#endif
writen(sock, (char *) &rank, sizeof(rank));
#ifdef DEBUG
fprintf(stderr, "sending dims");
#endif
dimp = DIMS(obj);
nels = 1;
for (i = 0; i < rank; ++i)
{
#ifdef DEBUG
fprintf(stderr, " d%d=%ld", i, *dimp);
#endif
writen(sock, (char *) dimp, sizeof(*dimp));
nels *= *dimp;
++dimp;
}
#ifdef DEBUG
fprintf(stderr, ". done with dims\n");
fprintf(stderr, "trying to write %ld * 4 bytes of data\n", nels);
#endif
elsPtr = ELEMENTS(obj);
writen(sock, (char *) elsPtr, sizeof(*elsPtr) * nels);
}
ObjPtr ReceiveExtraStuffRealArrayRaw(obj, connection)
ObjPtr obj, connection;
{
int sock, rank, i;
long *dimp, nels, oneDim;
real *elsPtr;
sock = ((ConnectionPtr) connection) -> sock;
readn(sock, (char *) &rank, sizeof(rank));
/* fprintf(stderr, "rank = %ld\n", */
#ifdef DEBUG
fprintf(stderr, "got rank = %d\n", rank);
#endif
RANK(obj) = rank;
#ifdef DEBUG
fprintf(stderr, "getting dims -");
#endif
dimp = Alloc(rank * sizeof(long));
DIMS(obj) = dimp;
nels = 1;
for (i = 0; i < rank; ++i)
{
readn(sock, (char *) &oneDim, sizeof(long));
nels *= oneDim;
*dimp = oneDim;
++dimp;
#ifdef DEBUG
fprintf(stderr, " d%d=%ld", i, oneDim);
#endif
}
#ifdef DEBUG
fprintf(stderr, ". done with dims\n");
#endif
elsPtr = (void *) Alloc(nels * sizeof(real));
if (!elsPtr)
{
OMErr();
return ObjFalse;
}
ELEMENTS(obj) = elsPtr;
#ifdef DEBUG
fprintf(stderr, "trying to read 4 * %d bytes\n", nels);
#endif
readn(sock, (char *) elsPtr, sizeof(real) * nels);
#ifdef DEBUG
fprintf(stderr, "...wow! did it work??\n");
#endif
}
ObjPtr TransmitExtraStuffRealArrayAscii(obj, connection)
ObjPtr obj, connection;
{
int sock;
int rank;
long *dimp;
long i;
long nels;
real *elsPtr;
sock = ((ConnectionPtr) connection) -> sock;
rank = RANK(obj);
#ifdef DEBUG
fprintf(stderr, "sending rank = %d.. ", rank);
#endif
sprintf(tempStr, "%d ", rank);
writen(sock, tempStr, strlen(tempStr));
#ifdef DEBUG
fprintf(stderr, "sending dims");
#endif
dimp = DIMS(obj);
nels = 1;
for (i = 0; i < rank; ++i)
{
#ifdef DEBUG
fprintf(stderr, " d%d=%ld", i, *dimp);
#endif
sprintf(tempStr, "%ld ", *dimp);
writen(sock, tempStr, strlen(tempStr));
nels *= *dimp;
++dimp;
}
#ifdef DEBUG
fprintf(stderr, ". done with dims\n");
fprintf(stderr, "trying to write %ld ascii numbers\n", nels);
#endif
elsPtr = ELEMENTS(obj);
for (i = 0; i < nels; ++i)
{
sprintf(tempStr, "%g ", elsPtr[i]);
writen(sock, tempStr, strlen(tempStr));
}
}
ObjPtr ReceiveExtraStuffRealArrayAscii(obj, connection)
ObjPtr obj, connection;
{
int sock, rank, i;
long *dimp, nels, oneDim;
real *elsPtr;
sock = ((ConnectionPtr) connection) -> sock;
rank = ReceiveRealAscii(connection);
#ifdef DEBUG
fprintf(stderr, "got rank = %d\n", rank);
#endif
RANK(obj) = rank;
#ifdef DEBUG
fprintf(stderr, "getting dims -");
#endif
dimp = Alloc(rank * sizeof(long));
DIMS(obj) = dimp;
nels = 1;
for (i = 0; i < rank; ++i)
{
oneDim = ReceiveRealAscii(connection);
nels *= oneDim;
*dimp = oneDim;
++dimp;
#ifdef DEBUG
fprintf(stderr, " d%d=%ld", i, oneDim);
#endif
}
#ifdef DEBUG
fprintf(stderr, ". done with dims\n");
#endif
elsPtr = (void *) Alloc(nels * sizeof(real));
if (!elsPtr)
{
OMErr();
return ObjFalse;
}
ELEMENTS(obj) = elsPtr;
#ifdef DEBUG
fprintf(stderr, "trying to read %ld elements..", nels);
#endif
for (i = 0; i < nels; ++i)
{
elsPtr[i] = ReceiveRealAscii(connection);
}
#ifdef DEBUG
fprintf(stderr, "wow! did it work??\n");
#endif
return ObjTrue;
}
ObjPtr TransmitExtraStuffObjectArraySpecial(obj, connection)
ObjPtr obj, connection;
{
int sock;
int rank;
long *dimp;
long i;
long nels;
ObjPtr *elsPtr;
double startTime;
startTime = Clock();
sock = ((ConnectionPtr) connection) -> sock;
rank = RANK(obj);
#ifdef DEBUG
fprintf(stderr, "sending rank = %d.. ", rank);
#endif
sprintf(tempStr, "%d ", rank);
writen(sock, tempStr, strlen(tempStr));
#ifdef DEBUG
fprintf(stderr, "sending dims");
#endif
dimp = DIMS(obj);
nels = 1;
for (i = 0; i < rank; ++i)
{
#ifdef DEBUG
fprintf(stderr, " d%d=%ld", i, *dimp);
#endif
sprintf(tempStr, "%ld ", *dimp);
writen(sock, tempStr, strlen(tempStr));
nels *= *dimp;
++dimp;
}
#ifdef DEBUG
fprintf(stderr, ". done with dims\n");
#endif
elsPtr = ELEMENTS(obj);
for (i = 0; i < nels; ++i)
{
TransmitObject(elsPtr[i], connection, false);
}
fprintf(stderr, "object array transmit time %10.4lf\n", Clock() - startTime);
}
ObjPtr ReceiveExtraStuffObjectArraySpecial(obj, connection)
ObjPtr obj, connection;
{
int sock, rank, i;
long *dimp, nels, oneDim;
ObjPtr *elsPtr;
double startTime;
startTime = Clock();
sock = ((ConnectionPtr) connection) -> sock;
rank = ReceiveRealAscii(connection);
#ifdef DEBUG
fprintf(stderr, "got rank = %d\n", rank);
#endif
RANK(obj) = rank;
#ifdef DEBUG
fprintf(stderr, "getting dims -");
#endif
dimp = Alloc(rank * sizeof(long));
DIMS(obj) = dimp;
nels = 1;
for (i = 0; i < rank; ++i)
{
oneDim = ReceiveRealAscii(connection);
nels *= oneDim;
*dimp = oneDim;
++dimp;
#ifdef DEBUG
fprintf(stderr, " d%d=%ld", i, oneDim);
#endif
}
#ifdef DEBUG
fprintf(stderr, ". done with dims\n");
#endif
elsPtr = (void *) Alloc(nels * sizeof(ObjPtr));
if (!elsPtr)
{
OMErr();
return ObjFalse;
}
ELEMENTS(obj) = elsPtr;
for (i = 0; i < nels; ++i)
{
((ConnectionPtr) connection) -> gotCmdEnd = false;
elsPtr[i] = ReceiveObject(connection, 0);
}
fprintf(stderr, "object array receive time %10.4lf\n", Clock() - startTime);
return ObjTrue;
}
#if 1
ObjPtr TransmitExtraStuffObjectArray(obj, connection)
ObjPtr obj, connection;
{
TransmitExtraStuffObjectArraySpecial(obj, connection);
}
#else
ObjPtr TransmitExtraStuffObjectArray(obj, connection)
ObjPtr obj, connection;
{
int sock;
int rank;
long *dimp;
long i;
long nels;
real *elsPtr;
sock = ((ConnectionPtr) connection) -> sock;
rank = RANK(obj);
#ifdef DEBUG
fprintf(stderr, "sending rank = %d.. ", rank);
#endif
sprintf(tempStr, "%d ", rank);
writen(sock, tempStr, strlen(tempStr));
#ifdef DEBUG
fprintf(stderr, "sending dims");
#endif
dimp = DIMS(obj);
nels = 1;
for (i = 0; i < rank; ++i)
{
#ifdef DEBUG
fprintf(stderr, " d%d=%ld", i, *dimp);
#endif
sprintf(tempStr, "%ld ", *dimp);
writen(sock, tempStr, strlen(tempStr));
nels *= *dimp;
++dimp;
}
#ifdef DEBUG
fprintf(stderr, ". done with dims\n");
#endif
}
#endif
#if 1
ObjPtr ReceiveExtraStuffObjectArray(obj, connection)
ObjPtr obj, connection;
{
ReceiveExtraStuffObjectArraySpecial(obj, connection);
}
#else
ObjPtr ReceiveExtraStuffObjectArray(obj, connection)
ObjPtr obj, connection;
{
int sock, rank, i;
long *dimp, nels, oneDim;
ObjPtr *elsPtr;
sock = ((ConnectionPtr) connection) -> sock;
rank = ReceiveRealAscii(connection);
#ifdef DEBUG
fprintf(stderr, "got rank = %d\n", rank);
#endif
RANK(obj) = rank;
#ifdef DEBUG
fprintf(stderr, "getting dims -");
#endif
dimp = Alloc(rank * sizeof(long));
DIMS(obj) = dimp;
nels = 1;
for (i = 0; i < rank; ++i)
{
oneDim = ReceiveRealAscii(connection);
nels *= oneDim;
*dimp = oneDim;
++dimp;
#ifdef DEBUG
fprintf(stderr, " d%d=%ld", i, oneDim);
#endif
}
#ifdef DEBUG
fprintf(stderr, ". done with dims\n");
#endif
elsPtr = (void *) Alloc(nels * sizeof(ObjPtr));
if (!elsPtr)
{
OMErr();
return ObjFalse;
}
ELEMENTS(obj) = elsPtr;
for (i = 0; i < nels; ++i)
{
elsPtr[i] = (ObjPtr) NETSTUBFLAG;
}
return ObjTrue;
}
#endif
ObjPtr TransmitExtraStuffString(obj, connection)
ObjPtr obj, connection;
{
int sock;
if (!obj)
return ObjFalse;
sock = ((ConnectionPtr) connection) -> sock;
if (sock < 0)
return ObjFalse;
/* HAK! should figure out a way to avoid relying on the \0 */
/* transmit everything, even the \0 on the end */
#ifdef DEBUG
fprintf(stderr, "%s", ((SPtr) obj) -> stringPtr);
#endif
writen(sock, ((SPtr) obj) -> stringPtr, 1 + strlen(((SPtr) obj) -> stringPtr));
return ObjTrue;
}
ObjPtr ReceiveExtraStuffString(obj, connection)
ObjPtr obj, connection;
{
double time;
int sock;
char inChar;
int someDigits;
/* HAK! figure out how to do this reentrantly */
time = Clock();
sock = ((ConnectionPtr) connection) -> sock;
someDigits = false;
if (obj)
{
char s[1000];
int si;
si = 0;
s[si] = '\0';
Free(((SPtr) obj) -> stringPtr); /* really! */
((SPtr) obj) -> stringPtr = (char *) 0;
while(Clock() < time + JOHNSTIMEOUT)
{
if (1 == read(sock, &inChar, 1))
{
if (inChar)
{
someDigits = true;
s[si++] = inChar;
s[si] = '\0';
}
if (!inChar || si >= 999)
{
if ( ! ((SPtr) obj) -> stringPtr)
{
((SPtr) obj) -> stringPtr = Alloc(1 + strlen(s));
if (! ((SPtr) obj) -> stringPtr)
{
OMErr();
return ObjFalse;
}
strcpy(((SPtr) obj) -> stringPtr, s);
}
else
{
((SPtr) obj) -> stringPtr = Realloc(((SPtr) obj) -> stringPtr, strlen(s));
if (! ((SPtr) obj) -> stringPtr)
{
OMErr();
return ObjFalse;
}
strcat(((SPtr) obj) -> stringPtr, s);
}
si = 0;
s[si] = '\0';
}
if (!inChar)
{
return ObjTrue;
}
}
}
/* only got here if we timed out */
fprintf(stderr, "hack timeout in ReceiveExtraStuffString");
return ObjFalse;
}
return ObjTrue;
}
ObjPtr TransmitExtraStuffObject(obj, connection)
ObjPtr obj, connection;
{
int sock;
if (!obj)
return ObjFalse;
sock = ((ConnectionPtr) connection) -> sock;
if (sock < 0)
return ObjFalse;
if (IsInt(obj))
{
char buf[50];
sprintf(buf, "%d ", ((IPtr) obj) -> intpart);
#ifdef DEBUG
fprintf(stderr, "%s", buf);
#endif
writen(sock, buf, strlen(buf));
}
else if (IsReal(obj))
{
char buf[100];
sprintf(buf, "%g ", ((RPtr) obj) -> realpart);
#ifdef DEBUG
fprintf(stderr, "%s", buf);
#endif
writen(sock, buf, strlen(buf));
}
return ObjTrue;
}
ObjPtr ReceiveExtraStuffObject(obj, connection)
ObjPtr obj, connection;
{
int sock;
char inChar;
int someDigits;
long int ltmp;
double time;
if (!obj)
return ObjFalse;
/* HAK! figure out how to do this reentrantly */
time = Clock();
ltmp = 0;
someDigits = false;
inChar = 'x';
sock = ((ConnectionPtr) connection) -> sock;
if (IsInt(obj))
{
while (Clock() < time + JOHNSTIMEOUT)
{
if (1 == read(sock, &inChar, 1))
{
if (isspace(inChar) && (inChar != '\n') && !someDigits)
{
/* skipping blanks */
}
else if (inChar >= '0' && inChar <= '9')
{
someDigits = true;
ltmp *= 10;
ltmp += inChar - '0';
}
else if (inChar == '\0' || inChar == '\n')
{
((ConnectionPtr) connection) -> gotCmdEnd = true;
return ObjFalse;
}
else
{
((IPtr) obj) -> intpart = ltmp;
return ObjTrue;
}
}
}
/* only got here if we timed out */
fprintf(stderr, "hack timeout in ReceiveExtraStuffObject");
return ObjFalse;
}
else if (IsReal(obj))
{
((RPtr) obj) -> realpart = ReceiveRealAscii(connection);
}
return ObjTrue;
}
#ifdef PROTO
ObjPtr TransmitExtraStuffPalette(ObjPtr obj, ObjPtr connection)
#else
ObjPtr TransmitExtraStuffPalette(obj, connection)
ObjPtr obj, connection;
#endif
{
return ObjTrue;
}
#ifdef PROTO
ObjPtr ReceiveExtraStuffPalette(ObjPtr obj, ObjPtr connection)
#else
ObjPtr ReceiveExtraStuffPalette(obj, connection)
ObjPtr obj, connection;
#endif
{
ObjPtr atomPal;
#if 0
atomPal = NewAtomicPalette(); /* HAK */
CopyPalette(obj, atomPal);
#endif
return ObjTrue;
}
#endif /* ifdef SOCKETS */
int PublishObject(obj)
ObjPtr obj;
/* Marks an object as published. Returns the (new?) NetworkID of the object,
* or 0 if it failed for some reason.
*/
{
int netid;
netid = 0;
#ifdef SOCKETS
if (!GetVar(obj, NETWORKID))
{
SetVar(obj, NETWORKID, NewInt(GetNetworkID()));
}
netid = GetInt(GetIntVar("PublishObject", obj, NETWORKID));
if (!IsPublished(obj))
{
obj -> flags = obj -> flags | ISPUBLISHED;
if (!allPublished)
{
fprintf(stderr, "Whoops! recreating allPublished!\n");
allPublished = NewList();
AddToReferenceList(allPublished);
}
PrefixList(allPublished, obj);
}
#endif
return netid;
}
#if 0
void UnPublishObject(obj)
ObjPtr obj;
/* Unmarks the published flag, removes object from published list */
{
#ifdef SOCKETS
if (IsPublished(obj))
{
#if 0
obj -> flags = obj -> flags & ~ISPUBLISHED;
#endif
DeleteFromList(allPublished, obj);
DeleteFromList(allAdvertised, obj);
#ifdef SAVEDELETED
if (!allDeletedPublished);
{
fprintf(stderr, "Whoops! recreating allDeletedPublished!\n");
allDeletedPublished = NewList();
AddToReferenceList(allDeletedPublished);
}
PrefixList(allDeletedPublished, obj);
#endif
}
#endif
}
#endif
ObjPtr FindPublishedObject(num)
unsigned long num;
{
#ifdef SOCKETS
ObjPtr retVal;
ThingListPtr runner;
retVal = ObjFalse;
if (allPublished)
{
runner = LISTOF(allPublished);
while (runner && (num != GetInt(GetIntVar("FindPublishedObject", runner -> thing, NETWORKID))))
{
runner = runner -> next;
}
if (runner)
{
retVal = runner -> thing;
}
}
/* if we didn't find it, try the list of Advertised objects */
if (!retVal && allAdvertised)
{
runner = LISTOF(allAdvertised);
while (runner && (num != GetInt(GetIntVar("FindPublishedObject", runner -> thing, NETWORKID))))
{
runner = runner -> next;
}
if (runner)
{
retVal = runner -> thing;
}
}
#ifdef SAVEDELETED
/* still not found, try the deleted list */
if (retVal && allDeletedPublished)
{
runner = LISTOF(allDeletedPublished);
while(runner && (num != GetInt(GetIntVar("FindPublishedObject", runner -> thing, NETWORKID))))
{
runner = runner -> next;
}
if (runner)
{
retVal = runner -> thing;
}
}
#endif
return retVal;
#else
return ObjFalse;
#endif
}
void InitNetObjects()
{
#ifdef SOCKETS
SetMethod(objClass, TRANSMITEXTRA, TransmitExtraStuffObject);
SetMethod(objClass, RECEIVEEXTRA, ReceiveExtraStuffObject);
SetMethod(stringClass, TRANSMITEXTRA, TransmitExtraStuffString);
SetMethod(stringClass, RECEIVEEXTRA, ReceiveExtraStuffString);
SetMethod(paletteClass, TRANSMITEXTRA, TransmitExtraStuffPalette);
SetMethod(paletteClass, RECEIVEEXTRA, ReceiveExtraStuffPalette);
SetMethod(objectArrayClass, TRANSMITEXTRA, TransmitExtraStuffObjectArraySpecial);
SetMethod(objectArrayClass, RECEIVEEXTRA, ReceiveExtraStuffObjectArraySpecial);
allPublished = NewList();
AddToReferenceList (allPublished);
#ifdef SAVEDELETED
allDeletedPublished = NewList();
AddToReferenceList (allDeletedPublished);
#endif
#endif
}
void KillNetObjects()
{
#ifdef SOCKETS
RemoveFromReferenceList(allPublished);
#endif
}